package com.siyoumi.aspect;

import com.siyoumi.component.api.jj.JJ;
import com.siyoumi.component.api.jj.RobotType;
import com.siyoumi.config.SysConfig;
import com.siyoumi.util.XDate;
import com.siyoumi.util.XLog;
import com.siyoumi.util.XStr;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.LocalDateTime;


@Aspect
@Component
@Slf4j
public class AspectLog {
    @Pointcut("execution(* com.siyoumi.service.*.*(..))")
    public void func() {

    }

    @Around(value = "func()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        String funcName = proceedingJoinPoint.getSignature().getName();
        funcName = XStr.concat("[", funcName, "]"); //方法名

        //XLog.debug(this.getClass(), funcName, "---BEGIN");
        if (proceedingJoinPoint.getArgs().length > 0) {
            //传入参数
            //XLog.debug(this.getClass(), funcName, "---args:", proceedingJoinPoint.getArgs());
        }

        //开始时间
        LocalDateTime begin = XDate.now();

        Object proceed = proceedingJoinPoint.proceed();//放行执行目标方法

        //计算执行时间
        Duration between = XDate.between(begin, XDate.now());
        long ms = between.toMillis(); //毫秒

        long msLongFunc = 1000 * 10;
        if (SysConfig.getIns().isDev()) {
            msLongFunc = 1000;
        }
        if (ms > msLongFunc) {
            log.info("{}---exec_time: {}ms", funcName, ms);
            log.info("{}---方法执行过慢", funcName);
            if (!SysConfig.getIns().isDev()) {
                //钉钉通知
                JJ jj = JJ.getIns(RobotType.ERROR);
                String msg = XStr.concat(funcName, "方法执行时间 " + ms, "ms > " + msLongFunc, "ms");
                jj.send(msg, null, true);
            }
        }

        //XLog.debug(this.getClass(), funcName, "---END");

        //返回目标方法返回值
        return proceed;
    }
}
